//package com.zlyx.easy.swagger.plugins;
//
//import static com.zlyx.easy.swagger.utils.Annotations.resolvedTypeFromOperation;
//import static com.zlyx.easy.swagger.utils.Annotations.resolvedTypeFromResponse;
//import static com.zlyx.easy.swagger.utils.ResponseHeaders.headers;
//import static com.zlyx.easy.swagger.utils.ResponseHeaders.responseHeaders;
//import static springfox.documentation.schema.ResolvedTypes.modelRefFactory;
//import static springfox.documentation.spi.schema.contexts.ModelContext.returnValue;
//
//import java.util.Iterator;
//import java.util.Map;
//import java.util.Optional;
//import java.util.Set;
//
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.core.annotation.Order;
//import org.springframework.http.HttpStatus;
//
//import com.fasterxml.classmate.ResolvedType;
//import com.fasterxml.classmate.TypeResolver;
//import com.zlyx.easy.core.collections.Lists;
//import com.zlyx.easy.swagger.annotations.SpringMapping;
//import com.zlyx.easy.swagger.config.EasySwaggerConfiguration;
//
//import io.swagger.annotations.ApiResponse;
//import io.swagger.annotations.ResponseHeader;
//import springfox.documentation.builders.ResponseMessageBuilder;
//import springfox.documentation.schema.ModelReference;
//import springfox.documentation.schema.TypeNameExtractor;
//import springfox.documentation.service.Header;
//import springfox.documentation.service.Operation;
//import springfox.documentation.service.ResponseMessage;
//import springfox.documentation.spi.DocumentationType;
//import springfox.documentation.spi.schema.contexts.ModelContext;
//import springfox.documentation.spi.service.OperationBuilderPlugin;
//import springfox.documentation.spi.service.contexts.OperationContext;
//import springfox.documentation.swagger.common.SwaggerPluginSupport;
//
//@Order(SwaggerPluginSupport.SWAGGER_PLUGIN_ORDER + 1)
//public class EasySwaggerResponseMessageReader implements OperationBuilderPlugin {
//
//	private final TypeNameExtractor typeNameExtractor;
//	private final TypeResolver typeResolver;
//
//	@Autowired
//	public EasySwaggerResponseMessageReader(TypeNameExtractor typeNameExtractor, TypeResolver typeResolver) {
//		this.typeNameExtractor = typeNameExtractor;
//		this.typeResolver = typeResolver;
//	}
//
//	@Override
//	public void apply(OperationContext context) {
//		context.operationBuilder().responseMessages(read(context));
//	}
//
//	@Override
//	public boolean supports(DocumentationType delimiter) {
//		return SwaggerPluginSupport.pluginDoesApply(delimiter);
//	}
//
//	protected Set<ResponseMessage> read(OperationContext context) {
////		Set<ResponseMessage> responseMessages = newHashSet();
////		Optional<SpringMapping> annotation = context.findAnnotation(SpringMapping.class);
////		if (annotation.isPresent() && !annotation.get().hidden()) {
////			Operation operation = context.operationBuilder().build();
////			ResolvedType defaultResponse = context.getReturnType();
////			Optional<ResolvedType> operationResponse = annotation
////					.transform(resolvedTypeFromOperation(typeResolver, defaultResponse));
////			Optional<ResponseHeader[]> defaultResponseHeaders = annotation.transform(responseHeaders());
////			Map<String, Header> defaultHeaders = newHashMap();
////			if (defaultResponseHeaders.isPresent()) {
////				defaultHeaders.putAll(headers(defaultResponseHeaders.get()));
////			}
////			Set<Integer> codes = getResponseCode(operation);
////			int[] responseCodes = annotation.get().codes();
////			com.zlyx.easy.swagger.model.ResponseMessage message = null;
////			for (int code : responseCodes) {
////				message = EasySwaggerConfiguration.getResponseMessage(code);
////				if (!codes.contains(code) && message != null) {
////					codes.add(code);
////					ModelContext modelContext = returnValue(context.getGroupName(), message.getResponseClass(),
////							context.getDocumentationType(), context.getAlternateTypeProvider(),
////							context.getGenericsNamingStrategy(), context.getIgnorableParameterTypes());
////					Optional<ModelReference> responseModel = Optional.absent();
////					ResolvedType type = operationResponse.get();
////					if (message.getResponseClass() != null) {
////						type = typeResolver.resolve(message.getResponseClass());
////					}
////					responseModel = Optional
////							.of(modelRefFactory(modelContext, typeNameExtractor).apply(context.alternateFor(type)));
////					responseMessages.add(new ResponseMessageBuilder().code(code).message(message.getMessage())
////							.responseModel(responseModel.orNull()).headersWithDescription(message.getHeaders())
////							.build());
////				}
////			}
////			ApiResponse[] apiResponseAnnotations = annotation.get().apiResponses();
////
////			for (ApiResponse apiResponse : apiResponseAnnotations) {
////				handleResponse(context, operationResponse, defaultHeaders, responseMessages, codes, apiResponse);
////			}
////			Optional<ApiResponse> response = context.findAnnotation(ApiResponse.class);
////			if (response.isPresent()) {
////				handleResponse(context, operationResponse, defaultHeaders, responseMessages, codes, response.get());
////			}
////		}
////		return responseMessages;
//	}
//
//	private void handleResponse(OperationContext context, Optional<ResolvedType> operationResponse,
//			Map<String, Header> defaultHeaders, Set<ResponseMessage> responseMessages, Set<Integer> codes,
//			ApiResponse apiResponse) {
//		if (!codes.contains(apiResponse.code())) {
//			codes.add(apiResponse.code());
//			ModelContext modelContext = returnValue(context.getGroupName(), apiResponse.response(),
//					context.getDocumentationType(), context.getAlternateTypeProvider(),
//					context.getGenericsNamingStrategy(), context.getIgnorableParameterTypes());
//			Optional<ModelReference> responseModel = Optional.absent();
//			Optional<ResolvedType> type = resolvedType(null, apiResponse);
//			if (isSuccessful(apiResponse.code())) {
//				type = type.or(operationResponse);
//			}
//			if (type.isPresent()) {
//				responseModel = Optional
//						.of(modelRefFactory(modelContext, typeNameExtractor).apply(context.alternateFor(type.get())));
//			}
//			Map<String, Header> headers = newHashMap(defaultHeaders);
//			headers.putAll(headers(apiResponse.responseHeaders()));
//			responseMessages.add(new ResponseMessageBuilder().code(apiResponse.code()).message(apiResponse.message())
//					.responseModel(responseModel.orNull()).headersWithDescription(headers).build());
//		}
//	}
//
//	private Set<Integer> getResponseCode(Operation operation) {
//		Set<Integer> codes = Lists.newHashSet();
//		Set<ResponseMessage> messages = operation.getResponseMessages();
//		Iterator<ResponseMessage> its = messages.iterator();
//		while (its.hasNext()) {
//			codes.add(its.next().getCode());
//		}
//		return codes;
//	}
//
//	static boolean isSuccessful(int code) {
//		try {
//			return HttpStatus.Series.SUCCESSFUL.equals(HttpStatus.Series.valueOf(code));
//		} catch (Exception ignored) {
//			return false;
//		}
//	}
//
//	private Optional<ResolvedType> resolvedType(ResolvedType resolvedType, ApiResponse apiResponse) {
//		return fromNullable(resolvedTypeFromResponse(typeResolver, resolvedType).apply(apiResponse));
//	}
//
//}
